﻿using SuperX.Common.Abstract;
using SuperX.Common.BasicService;
using SuperX.Common.Collection;
using SuperX.Common.Helper;
using SuperX.Common.Respository;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace SuperX.Common.Object
{
    // 
    public static class UidResource
    {
        // 
        static UidResource()
        {
            UidResource.IdToStringMap = new ConcurrentDictionary<long, string>();
            UidResource.LockObj = new object();
        }

        // 
        public static void Clear()
        {
            object lockObj = UidResource.LockObj;
            lock (lockObj)
            {
                UidResource.StringToIdMap.Clear();
                UidResource.UidToObjMap.Clear();
                UidResource.IdToStringMap.Clear();
            }
        }

        // 
        public static long GetNextUid(IBasicObject obj)
        {
            if (obj == null)
            {
                return 0L;
            }
            if (obj.Parent == null || string.IsNullOrWhiteSpace(obj.FullName))
            {
                return UidResource.GetUid();
            }
            if (UidResource.StringToIdMap.ContainsKey(obj.FullName))
            {
                return UidResource.StringToIdMap[obj.FullName];
            }
            object lockObj = UidResource.LockObj;
            lock (lockObj)
            {
                UidResource._nextId += 1L;
            }
            return UidResource._nextId;
        }

        // 
        public static long GetCurrentGerUid()
        {
            return UidResource._nextId;
        }

        // 
        public static long GetUid()
        {
            long num;
            do
            {
                num = GenerateUid.GenerateSnowFlake();
            }
            while (UidResource.UidToObjMap.ContainsKey(num));
            return num;
        }

        // 
        public static void UpdateUid(string fullName, long uid)
        {
            object lockObj = UidResource.LockObj;
            lock (lockObj)
            {
                if (uid > UidResource._nextId && uid < 2147483647L)
                {
                    UidResource._nextId = uid;
                }
            }
            UidResource.Update(fullName, uid);
        }

        // 
        internal static void RemoveChildGroupObject(IObjCollection parent)
        {
            if (parent == null)
            {
                return;
            }
            List<IBasicObject> values = parent.GetValues();
            IProjService serverHost = BasicServiceManager.GetProjService();
            if (serverHost != null)
            {
                IProject project = serverHost.Project;
            }
            foreach (IBasicObject baseObject in values)
            {
                BasicObject.Remove(baseObject.FullName, baseObject);
                IObjCollection objCollection = baseObject as IObjCollection;
                if (objCollection != null)
                {
                    UidResource.RemoveChildGroupObject(objCollection);
                }
            }
        }

        // 
        public static void AddChildGroupObject(IObjCollection parent)
        {
            if (parent == null)
            {
                return;
            }
            List<IBasicObject> values = parent.GetValues();
            IProjService serverHost = BasicServiceManager.GetProjService();
            if (serverHost != null)
            {
                IProject project = serverHost.Project;
            }
            foreach (IBasicObject baseObject in values)
            {
                BasicObject.Add(baseObject.FullName, baseObject);
                IObjCollection objCollection = baseObject as IObjCollection;
                if (objCollection != null)
                {
                    UidResource.AddChildGroupObject(objCollection);
                }
            }
        }

        // 
        public static void UpdateSubObjFullNameIdMap(IObjCollection parent)
        {
            if (parent == null)
            {
                return;
            }
            List<IBasicObject> values = parent.GetValues();
            IProjService serverHost = BasicServiceManager.GetProjService();
            IProject project = (serverHost != null) ? serverHost.Project : null;
            foreach (IBasicObject baseObject in values)
            {
                IBasicObject baseObject2;
                if (project != null && (!project.Objects.TryGetValue(baseObject.FullName, out baseObject2) || baseObject2 != baseObject))
                {
                    string text = baseObject.FullName.Substring(baseObject.FullName.IndexOf('.') + 1);
                    while (!string.IsNullOrEmpty(text))
                    {
                        BasicObject.Remove(text, baseObject);
                        int num = text.IndexOf('.') + 1;
                        if (num == 0)
                        {
                            break;
                        }
                        text = text.Substring(num);
                    }
                    BasicObject.Add(baseObject.FullName, baseObject);
                }
                IObjCollection objCollection = baseObject as IObjCollection;
                if (objCollection != null)
                {
                    UidResource.UpdateSubObjFullNameIdMap(objCollection);
                }
            }
        }

        // 
        private static void Update(string fullName, long uid)
        {
            if (UidResource.IdToStringMap.ContainsKey(uid))
            {
                if (UidResource.IdToStringMap[uid] != fullName)
                {
                    long num;
                    UidResource.StringToIdMap.TryRemove(UidResource.IdToStringMap[uid], out num);
                    if (UidResource.StringToIdMap.ContainsKey(fullName))
                    {
                        long key = UidResource.StringToIdMap[fullName];
                        UidResource.StringToIdMap.TryRemove(fullName, out num);
                        if (UidResource.IdToStringMap.ContainsKey(key))
                        {
                            string text;
                            UidResource.IdToStringMap.TryRemove(key, out text);
                        }
                    }
                    UidResource.StringToIdMap.TryAdd(fullName, uid);
                    UidResource.IdToStringMap[uid] = fullName;
                    return;
                }
            }
            else
            {
                if (UidResource.StringToIdMap.ContainsKey(fullName))
                {
                    UidResource.StringToIdMap[fullName] = uid;
                }
                else
                {
                    UidResource.StringToIdMap.TryAdd(fullName, uid);
                }
                UidResource.IdToStringMap.TryAdd(uid, fullName);
            }
        }

        // 
        public static void AddUidObj(long uid, IBasicObject obj)
        {
            if (UidResource.UidToObjMap.ContainsKey(uid))
            {
                UidResource.UidToObjMap[uid] = obj;
                return;
            }
            UidResource.UidToObjMap.TryAdd(uid, obj);
        }

        // 
        public static void RemoveUidObj(long uid)
        {
            if (UidResource.UidToObjMap.ContainsKey(uid))
            {
                IBasicObject baseObject = UidResource.UidToObjMap[uid];
                IBasicObject baseObject2;
                UidResource.UidToObjMap.TryRemove(uid, out baseObject2);
            }
            if ((uid > 2147483647L || uid <= 0L) && UidResource.IdToStringMap.ContainsKey(uid))
            {
                long num;
                UidResource.StringToIdMap.TryRemove(UidResource.IdToStringMap[uid], out num);
                string text;
                UidResource.IdToStringMap.TryRemove(uid, out text);
            }
        }

        // 
        public static string GetFullName(long uid)
        {
            if (!UidResource.UidToObjMap.ContainsKey(uid))
            {
                return string.Empty;
            }
            return UidResource.UidToObjMap[uid].FullName;
        }

        // 
        public static IBasicObject GetObjByUid(long uid)
        {
            if (!UidResource.UidToObjMap.ContainsKey(uid))
            {
                return null;
            }
            return UidResource.UidToObjMap[uid];
        }

        // 
        public static IBasicObject GetObjByFullName(string fullName)
        {
            long uid = UidResource.GetUid(fullName);
            if (!UidResource.UidToObjMap.ContainsKey(uid))
            {
                return null;
            }
            return UidResource.UidToObjMap[uid];
        }

        // 
        public static long GetUid(string fullName)
        {
            if (!UidResource.StringToIdMap.ContainsKey(fullName))
            {
                return 0L;
            }
            return UidResource.StringToIdMap[fullName];
        }

        // 
        public static void Save(string fileDir)
        {
            if (!Directory.Exists(fileDir))
            {
                Directory.CreateDirectory(fileDir);
            }
            new JsonRepository(Path.Combine(fileDir, "UIDResource.SConfig"), UidResource.StringToIdMap, false).Save();
        }

        // 
        public static void Load(string fileDir)
        {
            string text = Path.Combine(fileDir, "UIDResource.SConfig");
            if (!File.Exists(text))
            {
                return;
            }
            JsonRepository jsonRepository = new JsonRepository(text);
            jsonRepository.Load(typeof(ConcurrentDictionary<string, long>));
            if (!(jsonRepository.Model is ConcurrentDictionary<string, long>))
            {
                return;
            }
            UidResource.StringToIdMap = (ConcurrentDictionary<string, long>)jsonRepository.Model;
            foreach (KeyValuePair<string, long> keyValuePair in UidResource.StringToIdMap)
            {
                if (keyValuePair.Value > UidResource._nextId && keyValuePair.Value < 2147483647L)
                {
                    UidResource._nextId = keyValuePair.Value;
                }
                if (UidResource.IdToStringMap.ContainsKey(keyValuePair.Value))
                {
                    UidResource.IdToStringMap[keyValuePair.Value] = keyValuePair.Key;
                }
                else
                {
                    UidResource.IdToStringMap.TryAdd(keyValuePair.Value, keyValuePair.Key);
                }
            }
        }

        // 
        private const string FileName = "UIDResource.SConfig";

        //
        private static long _nextId;

        // 
        public const long MaxAutoId = 2147483647L;

        //
        private static ConcurrentDictionary<string, long> StringToIdMap = new ConcurrentDictionary<string, long>();

        // 
        private static readonly ConcurrentDictionary<long, string> IdToStringMap;

        //
        private static readonly ConcurrentDictionary<long, IBasicObject> UidToObjMap = new ConcurrentDictionary<long, IBasicObject>();

        // 
        private static readonly object LockObj;
    }
}
